package wps.component {

import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.text.engine.TextLine;

import mx.binding.utils.ChangeWatcher;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.graphics.BitmapScaleMode;
import mx.managers.DragManager;

import spark.components.BorderContainer;
import spark.components.Group;
import spark.components.Image;
import spark.components.Label;
import spark.components.supportClasses.Skin;

import wps.constant.DragConst;
import wps.skin.ElementFocusPaneHoverSkin;
import wps.skin.ElementFocusPaneSelectedSkin;

public class DrawingBoard extends Group {

    //--------------------------------------------------------------------------
    //
    // Constants
    //
    //--------------------------------------------------------------------------

    /**
     * 用于注册对象，作为键名称
     */
    public static const NAME:String = "drawingboard";

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    // selectedElement
    //----------------------------------

    private var _selectedElelemt:UIComponent;

    [Bindable]
    /**
     * 选中的元素
     */
    public function get selectedElement():UIComponent {
        return _selectedElelemt;
    }

    public function set selectedElement(selectedElement:UIComponent):void {
        _selectedElelemt = selectedElement;

        selectedElementChanged();
    }

    //----------------------------------
    // hoverElement
    //----------------------------------

    private var _hoverElement:UIComponent;

    /**
     * 鼠标经过的元素
     */
    private function get hoverElement():UIComponent {
        return _hoverElement;
    }

    private function set hoverElement(hoverElement:UIComponent):void {
        if (_hoverElement != hoverElement) {
            _hoverElement = hoverElement;
            hoverElementChanged();
        }
    }

    //----------------------------------
    // selectedFocusPane
    //----------------------------------

    /**
     * 选择元素时显示的框
     */
    private var _selectedFocusPane:ElementFocusPane;

    //----------------------------------
    // hoverFocuPane
    //----------------------------------

    /**
     * 鼠标经过非选中元素时显示的框
     */
    private var _hoverFocuPane:ElementFocusPane;

    /**
     * 拖动元素时为true，在dropEnter事件中设为false
     */
    private var _draggingElement:Boolean = false;

    /**
     * mouse coordinate when dray start
     */
    private var _dragStartPoint:Point;

    /**
     * element coordinate when dray start
     */
    private var _dragStartElementPoint:Point;

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    public function DrawingBoard() {
        super();

        clipAndEnableScrolling = true;

        initFocusPane();
        addEventHandler();
    }

    //--------------------------------------------------------------------------
    //
    // Methods
    //
    //--------------------------------------------------------------------------
	
	/**
	 * 移除焦点框
	 */
	public function removeFocusPane():void {
		if (contains(_hoverFocuPane)) {
			removeElement(_hoverFocuPane);
		}
		if (contains(_selectedFocusPane)) {
			removeElement(_selectedFocusPane);
		}
	}

    private function initFocusPane():void {
        _hoverFocuPane = new ElementFocusPane();
        _selectedFocusPane = new ElementFocusPane();

        _hoverFocuPane.setStyle("skinClass", Class(ElementFocusPaneHoverSkin));
        _selectedFocusPane.setStyle("skinClass", Class(ElementFocusPaneSelectedSkin));

        // 当划过的焦点框和选中的焦点框重叠时，划过的焦点框在上面
        _hoverFocuPane.depth = ElementFocusPane.DEPTH;
        _selectedFocusPane.depth = ElementFocusPane.DEPTH - 1;
    }

    private function addEventHandler():void {
        addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
        addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
        addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
        addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
    }

    private function hoverElementChanged():void {
        // 如果划过选中的元素不做处理
        if (_hoverElement && (_hoverElement == _selectedElelemt)) {
            return;
        }

        _hoverFocuPane.target = _hoverElement;
    }

    private function selectedElementChanged():void {
        _selectedFocusPane.target = selectedElement;
        setFocusPaneVisible(_hoverFocuPane, false);

        // 监听位置和大小变化
        ChangeWatcher.watch(_selectedElelemt, "x", selectedElementXListener);
        ChangeWatcher.watch(_selectedElelemt, "y", selectedElementYListener);
        ChangeWatcher.watch(_selectedElelemt, "width", selectedElementWidthListener);
        ChangeWatcher.watch(_selectedElelemt, "height", selectedElementHeightListener);
        ChangeWatcher.watch(_selectedElelemt, "scaleMode", selectedElementScaleModeListener);
    }

    /**
     * 设置焦点框是否可见
     */
    private function setFocusPaneVisible(pane:ElementFocusPane, value:Boolean):void {
        if (value) {
            addElement(pane);
        } else {
            if (contains(pane)) {
                removeElement(pane);
            }
        }
    }

    /**
     * 找到鼠标所在坐标下的最上层元素
     */
    private function findTopChild(e:MouseEvent):UIComponent {
        var p:Point = new Point(e.stageX, e.stageY);

        // 调用getObjectsUnderPoint方法的必须是Application对象，否则返回空数组
        var objects:Array = parentApplication.getObjectsUnderPoint(p);

        var top:UIComponent;

        for (var o:* in objects) {
            var object:Object = objects[o];
            var child:UIComponent;

            if (object is Skin) {
                // 图片
                var skin:Skin = object as Skin;
                if (skin["hostComponent"]) {
                    child = skin["hostComponent"] as UIComponent;
                }
            } else if (object is TextLine) {
                // 文本。当鼠标移到Label上时，鼠标下的控件是TextLine，而Label是TextLine的parent
                var textLine:TextLine = object as TextLine;
                if (textLine.parent is UIComponent) {
                    child = textLine.parent as UIComponent;
                }
            }

            if (child != this && contains(child) && child.depth < (ElementFocusPane.DEPTH - 1)) {
                if (!top) {
                    top = child;
                } else {
                    top = top.depth <= child.depth ? child : top;
                }
            }
        }

        return top;
    }

    /**
     * 拖动选择的元素
     */
    private function dragElement(element:UIComponent, e:MouseEvent):void {
        var point:Point = new Point(e.stageX, e.stageY);
        var distanceX:Number = point.x - _dragStartPoint.x;
        var distanceY:Number = point.y - _dragStartPoint.y;

        var oldX:Number = _dragStartElementPoint.x;
        var oldY:Number = _dragStartElementPoint.y;

        var xx:Number = oldX + distanceX;
        var yy:Number = oldY + distanceY;

        element.x = xx;
        element.y = yy;
        // validateElementPosition(element);
    }

    /**
     * 确保图片位置在画板内
     */
    private function validateElementPosition(element:UIComponent):void {
        var xx:Number = element.x;
        var yy:Number = element.y;

        xx = xx < 0 ? 0 : xx;
        yy = yy < 0 ? 0 : yy;

        xx = (xx + element.width) > width ? width - element.width : xx;
        yy = (yy + element.height) > height ? height - element.height : yy;

        element.x = xx;
        element.y = yy;
    }

    /**
     * 确保图片大小不会超过画板
     */
    private function validateElementSize(element:UIComponent):void {

    }

    //--------------------------------------------------------------------------
    //
    // Event handlers
    //
    //--------------------------------------------------------------------------

    private function mouseMoveHandler(e:MouseEvent):void {
        // 当拖动元素时不显示划过元素的焦点
        if (!_draggingElement) {
            hoverElement = findTopChild(e);
        }

        if (e.buttonDown) {
            if (_selectedElelemt && _draggingElement) {
                dragElement(_selectedElelemt, e);
            }
        }
    }

    private function mouseDownHandler(e:MouseEvent):void {
        selectedElement = findTopChild(e);

        if (selectedElement) {
            // 记录开始拖动时的坐标
            _dragStartPoint = new Point(e.stageX, e.stageY);
            _dragStartElementPoint = new Point(selectedElement.x, selectedElement.y);
            _draggingElement = true;
        }
    }

    private function mouseUpHandler(e:MouseEvent):void {
        if (_draggingElement) {
            _draggingElement = false;
        }
    }

    private function mouseOutHandler(e:MouseEvent):void {

    }

    private function dragEnterHandler(e:DragEvent):void {
        var ds:DragSource = e.dragSource;
        if (ds.hasFormat(DragConst.IMAGE) || ds.hasFormat(DragConst.TEXT)) {
            var target:UIComponent = e.currentTarget as UIComponent;
            DragManager.acceptDragDrop(target);

            // 添加元素时避免移动已经选中的元素
            _draggingElement = false;
        }
    }

    private function dragDropHandler(e:DragEvent):void {
        var ds:DragSource = e.dragSource;

        var element:UIComponent;

        if (ds.hasFormat(DragConst.IMAGE)) {
            var image:Image = ds.dataForFormat(DragConst.IMAGE) as Image;

            var img:DrawingImage = new DrawingImage();
            img.source = image.source;
            element = img;

        } else if (ds.hasFormat(DragConst.TEXT)) {
            var label:Label = ds.dataForFormat(DragConst.TEXT) as Label;

            var text:DrawingText = new DrawingText();
            text.text = label.text;
            element = text;

        } else {
            return;
        }

        var xoffset:Number = ds.dataForFormat(DragConst.XOFFSET) as Number;
        var yoffset:Number = ds.dataForFormat(DragConst.YOFFSET) as Number;
        var w:Number = ds.dataForFormat(DragConst.WIDTH) as Number;
        var h:Number = ds.dataForFormat(DragConst.HEIGHT) as Number;

        // 使得图片放下时所在的位置和拖动时一样
        element.x = mouseX - xoffset;
        element.y = mouseY - yoffset;

        // 图片放置范围不能超过画板大小
//        element.x = element.x < 0 ? 0 : element.x;
//        element.y = element.y < 0 ? 0 : element.y;
//
//        element.x = (element.x + w) > width ? width - w : element.x;
//        element.y = (element.y + h) > height ? height - h : element.y;

        addElement(element);
    }

    private function selectedElementXListener(e:Event):void {
        // validateElementPosition(_selectedElelemt);
    }

    private function selectedElementYListener(e:Event):void {
        // validateElementPosition(_selectedElelemt);
    }

    private function selectedElementWidthListener(e:Event):void {
        if (_selectedElelemt is Image) {
            var image:Image = _selectedElelemt as Image;

            var originalW:Number = image.bitmapData.width;
            var originalH:Number = image.bitmapData.height;

            // 约束比例
            if (BitmapScaleMode.LETTERBOX == image.scaleMode) {
                image.height = Math.round(originalH / (originalW / image.width));
            }
        }

        // validateElementSize(_selectedElelemt);
    }

    private function selectedElementHeightListener(e:Event):void {
        if (_selectedElelemt is Image) {
            var image:Image = _selectedElelemt as Image;

            var originalW:Number = image.bitmapData.width;
            var originalH:Number = image.bitmapData.height;

            // 约束比例
            if (BitmapScaleMode.LETTERBOX == image.scaleMode) {
                image.width = Math.round(originalW / (originalH / image.height));
            }
        }

        // validateElementSize(_selectedElelemt);
    }

    private function selectedElementScaleModeListener(e:Event):void {
        // 由不约束比例转为约束时，始终根据宽度比例来设置高度
        selectedElementWidthListener(e);
    }

}
}
